from utils.util import *
from utils.global_variables import Data
import re


class Node():

    def __init__(self, expr='', op=None, fa=None, code='', level=0, children=None, has_bra=False):

        if op not in ['if', 'elseif', 'else']:
            self.has_bra, self.expr = delete_bracket(expr)
        else:
            self.has_bra = False
            self.expr = expr.strip()
        self.code = code
        self.father = fa
        if children != None:
            self.children = children
        else:
            self.children = []
        self.op = op
        self.level = level
        self.lines = None

    @classmethod
    def from_Node(cls, node):

        return cls(node.expr, node.op, node.father, node.code, node.level, node.children, node.has_bra)

    def modify_expr(self, new_expr):

        # delete extra brackets
        self.has_bra, self.expr = delete_bracket(new_expr)

    def add_child(self, child, pos=-1):

        # add one child in the self.children list at position pos
        if pos == -1:
            self.children.append(child)
        else:
            self.children = self.children[:pos] + [child] + self.children[pos:]
        child.set_father(self)
        if self.op in ['branch', 'loop', 'loop_while']:
            child.level = self.level + 1
        else:
            child.level = self.level
        if (start_pos := self.expr.find(child.expr)) != -1:
            if self.lines != None:
                start_line = self.lines[0] + self.expr[:start_pos].count('\n')
                end_line = start_line + child.expr.count('\n')
                child.lines = start_line, end_line
        elif self.lines != None:
            child.lines = self.lines

    def delete_child(self, child):

        for i in range(len(self.children)):
            if self.children[i] == child:
                self.children = self.children[:i] + self.children[i + 1:]
                break

    def clear_children(self):

        self.children = []

    def add_sibling(self, sib):

        fa = self.father
        pos = -1
        for i in range(fa.children):
            if self == fa.children[i]:
                fa.add_child(sib, i + 1)
                break

    def set_father(self, fa):

        self.father = fa

    def set_op(self, op):

        self.op = op

    def set_level(self, lvl):

        self.level = lvl

    def set_code(self, code):

        self.code = code

    def set_lines(self, lines):

        self.lines = lines

    def fail_to_generate(self):

        self.op = 'fail'
        self.code = '@@@failure@@@'

    def copy_node(self, node):

        self.has_bra = node.has_bra
        self.expr = node.expr
        self.code = node.code
        self.children = node.children
        self.op = node.op
        # self.father = node.father
        self.level = node.level

    def generate_code(self):

        if self.op == 'condition':
            self.code = self.children[0].code
            if self.has_bra:
                self.code = '({})'.format(self.code)
        elif self.op == 'else':
            self.code += ('    ' * (self.level - 1) + 'else {' + '\n')
            self.code += self.children[0].code
            self.code += '\n' + '    ' * (self.level - 1) + '}'
        elif self.op == 'body' or self.op == 'branch':
            if self.code != '':
                return
            for child in self.children:
                self.code += child.code
                if child != self.children[-1]:
                    self.code += '\n'
        elif self.op == 'if' or self.op == 'elseif':
            if self.op == 'if':
                key_word = 'if'
            else:
                key_word = 'else if'
            cond = self.children[0].code
            body = self.children[1].code
            self.code += ('    ' * (self.level - 1) + key_word + ' (')
            self.code += (cond + ') {\n' + body + '\n' + '    ' * (self.level - 1) + '}')
        elif self.op == 'loop_condition':
            init_ = recong_float(self.children[0].code, True)
            cond_ = recong_float(self.children[1].code, True)
            increment_ = recong_float(self.children[2].code, True)
            self.code = f'{init_}; {cond_}; {increment_}'
        elif self.op == 'loop':
            loop_cond = self.children[0].code
            body = self.children[1].code
            self.code += ('    ' * self.level + 'for' + ' (')
            self.code += (loop_cond + ') {\n' + body + '\n' + '    ' * self.level + '}')
        elif self.op == 'loop_while':
            loop_cond = self.children[0].code
            body = self.children[1].code
            self.code += ('    ' * self.level + 'while' + ' (')
            self.code += (loop_cond + ') {\n' + body + '\n' + '    ' * self.level + '}')
        elif self.op == 'none':
            self.father.delete_child(self)
        elif self.op == 'note':
            pass
        else:
            if self.father != None and self.father.op in ['body']:
                if self.has_bra:
                    self.code = '(' + '    ' * self.level + self.code + ');'
                else:
                    self.code = '    ' * self.level + self.code + ';'
                if len(self.children) > 0 and self.children[-1].op == 'body':
                    self.code = self.code[:-1]
            else:
                if self.has_bra:
                    if self.code[0] == '(' and bracket_match(self.code, 0) == len(self.code) - 1:
                        return
                    else:
                        self.code = '({})'.format(self.code)
            if '#' in self.code:
                self.code = "// " + self.code[self.code.find('#') + 1:-1].lstrip()
        # print ("pre: ", self.code)


def recong_float(s, flag):
    # 识别是不是含有小数
    s_ = s.split(' ')
    pattern1 = r'^([(]*)(-?\d+(\.\d+))([)]*)(?:,|;)?$'
    pattern2 = r'^([(]*)(-?\d+)([)]*)(?:,|;)?$'
    if flag == True:
        f = False
        for i in s_:
            if bool(re.match(pattern1, i)):
                f = True
        if f:
            t = 0
            for i in s_:
                if bool(re.match(pattern2, i)):
                    if ')' in s_[t]:
                        s_t = s_[t]
                        i = s_[t].find(')')
                        s_[t] = s_[t][:-len(s_[t]) + i] + '.0'
                        j = 1
                        while (j <= len(s_t) - i - 1):
                            s_[t] += ')'
                            j = j + 1
                        if s_t[len(s_t) - 1] != ')':
                            s_[t] += s_t[len(s_t) - 1]
                        else:
                            s_[t] += ')'
                    elif '(' in s_[t]:
                        s_[t] = s_[t] + '.0'
                    elif ';' in s_[t]:
                        s_[t] = s_[t][:-1] + '.0;'
                    elif ',' in s_[t]:
                        s_[t] = s_[t][:-1] + '.0,'
                    else:
                        s_[t] = s_[t] + '.0'
                t = t + 1
        s = ' '.join(s_)
        return s
    else:
        t = 0
        for i in s_:
            if bool(re.match(pattern2, i)):
                if ')' in s_[t]:
                    s_t = s_[t]
                    i = s_[t].find(')')
                    s_[t] = s_[t][:-len(s_[t]) + i] + '.0'
                    j = 1
                    while (j <= len(s_t) - i - 1):
                        s_[t] += ')'
                        j = j + 1
                    if s_t[len(s_t) - 1] != ')':
                        s_[t] += s_t[len(s_t) - 1]
                    else:
                        s_[t] += ')'
                elif '(' in s_[t]:
                    s_[t] = s_[t] + '.0'
                elif ';' in s_[t]:
                    s_[t] = s_[t][:-1] + '.0;'
                elif ',' in s_[t]:
                    s_[t] = s_[t][:-1] + '.0,'
                else:
                    s_[t] = s_[t] + '.0'
            t = t + 1
    s = ' '.join(s_)
    return s


def get_var_dim_and_type(data: Data, node: Node):
    q = [node]
    dim, ty = '1*1', 'float64'
    if q[0].code.isdigit():
        # 是整数
        ty = 'siint32'
        return dim, ty
    # bfs，启发式地探测结点维度和类型，不一定对
    while len(q) > 0:
        t = q[0]
        q = q[1:]
        for child in t.children:
            q.append(child)
        if t.op != 'var':
            continue
        if t.code in data.global_vars.keys():
            dim = data.global_vars[t.code]['dim']
            ty = data.global_vars[t.code]['type']
            return dim, ty
        elif t.code in data.tmp_dict.keys():
            dim = data.tmp_dict[t.code]['dim']
            ty = data.tmp_dict[t.code]['type']
            return dim, ty
        elif t.code in data.const_dict.keys():
            dim = data.const_dict[t.code]['dim']
            ty = data.const_dict[t.code]['type']
            return dim, ty
    return dim, ty


def func_node_process(func_name: str, data: Data, node: Node, func_node: Node):
    # node->Node: original node which is parsing
    # func_node: already parsed node(latex symbol or function), whose expr is part of node's expr
    # a independent sentence to process the function is needed

    # 从函数字典中获取基础信息
    return_type = data.func_dict[func_name]['return_type']
    out_type = data.func_dict[func_name]['output_type']
    out_dim = data.func_dict[func_name]['output_dim']
    type_list = get_args_type(data.func_dict[func_name]["raw_func"])

    arg_num = len(func_node.children)  # 伪代码中书写的参数数量
    raw_func = data.func_dict[func_name]['raw_func'].strip()
    ori_num = raw_func.count(',') + 1  # 函数签名中实际的参数数量
    if ori_num == 1:
        r = raw_func.rfind(')')
        l = bracket_match(raw_func, r)
        if raw_func[l + 1:r].strip() == '':
            ori_num = 0
    # 如果伪代码写的参数数量和函数签名中的参数数量不一致 (e.g. 函数签名: void func(int* out, int* in), 伪代码: a=func(b))
    if arg_num + 1 == ori_num:
        if node.father.op == '=':
            pos = func_node.code.find('(')
            res = node.father.children[0].code  # 左值变量
            var_dicts = {**data.global_vars, **data.tmp_dict, **data.const_dict}
            # 左值不在字典里，推荐变量名
            if res not in var_dicts:
                var_name = data.get_recommend_name(res)
                data.tmp_dict[var_name] = {'type': out_type, 'dim': out_dim}
                if res != var_name:
                    data.tmp_dict[res] = {'name': var_name, 'type': out_type, 'dim': out_dim}
                node.father.children[0].code = var_name
                res = var_name
            # 参数类型匹配
            var_list = [res]
            for c in func_node.children:
                var_list.append(c.code)
            arg_list = data.get_args(var_list, type_list)
            if arg_list == None:
                erro_print(traceback.extract_stack(), 'Function arguments type not matched')
                return
            new_code = func_node.code[:pos] + '(' + ', '.join(arg_list) + ')'
            func_node.set_code(new_code)
            func_node.set_op('hook')  # hook表示这种参数数量不匹配的节点情况
            return
        else:
            # 函数调用在运算表达式中，e.g. 函数签名: void func(int* out, int* in), 伪代码: a = b*func(c)*d
            res = data.get_tmp_var()
            data.tmp_dict[res] = {'type': out_type, 'dim': out_dim}
            # 找到第一个op为'body'的祖先节点，插入函数调用语句
            fa = node.father
            son = node
            while fa.op != 'body':
                son = fa
                fa = fa.father
            for i in range(len(fa.children)):
                if fa.children[i] == son:
                    func_line = Node(op='func')
                    var_list = [res]
                    for c in func_node.children:
                        var_list.append(c.code)
                    arg_list = data.get_args(var_list, type_list)
                    if arg_list == None:
                        erro_print(traceback.extract_stack(), 'Function arguments type not matched')
                        return
                    l = func_node.code.find('(')
                    new_code = func_node.code[:l + 1] + ', '.join(arg_list) + ')'
                    func_line.set_code(new_code)
                    fa.add_child(func_line, i)
                    func_line.generate_code()
                    if node in fa.children:
                        fa.delete_child(node)
                    break
            func_node.set_code(res)
            dims = out_dim.split('*')
            if len(set(dims)) == 1 and list(set(dims))[0] == '1':
                func_node.set_op('var')
            else:
                func_node.set_op('matrix')
            func_node.clear_children()
    elif arg_num + 1 < ori_num:
        if node.father.op == '=':
            # 例：函数签名：void func(int* a, int* b, int c)伪代码：{a, b} = func(c);
            outs = node.father.children[0].code
            if outs != "" and outs[0] == '{' and bracket_match(outs, 0) == len(outs) - 1:
                out_vars = outs[1:-1].split(',')
                if len(out_vars) != ori_num - arg_num:
                    erro_print(traceback.extract_stack(),
                               'Function arguments not matched, {}!'.format(node.father.expr))
                    return
                    # raise Exception('Function arguments not matched, {}!'.format(node.father.expr))
                var_list = []
                for i in range(len(out_vars)):
                    res = out_vars[i].strip()
                    var_dicts = {**data.global_vars, **data.tmp_dict, **data.const_dict}  # 每次更新var_dicts以防更新
                    # 左值不在字典里，推荐变量名
                    if res not in var_dicts:
                        var_name = data.get_recommend_name(res)
                        data.tmp_dict[var_name] = {'type': out_type.split(',')[i].strip(),
                                                   'dim': out_dim.split(',')[i].strip()}
                        if res != var_name:
                            data.tmp_dict[res] = {'name': var_name, 'type': out_type.split(',')[i].strip(),
                                                  'dim': out_dim.split(',')[i].strip()}
                        out_vars[i] = var_name
                    var_list.append(res)
                for c in func_node.children:
                    var_list.append(c.code)
                arg_list = data.get_args(var_list, type_list)
                if arg_list == None:
                    erro_print(traceback.extract_stack(), 'Function arguments type not matched')
                    return
                pos = func_node.code.find('(')
                new_code = func_node.code[:pos] + '(' + ', '.join(arg_list) + ')'
                func_node.set_code(new_code)
                func_node.set_op('hook')
                return
            else:
                erro_print(traceback.extract_stack(), f"Function multi-return-value not correct, {node.father.expr}!")
    elif arg_num == ori_num:
        # 找到第一个op为'body'的祖先节点，插入函数调用语句
        fa = node.father
        var_list = []
        for c in func_node.children:
            var_list.append(c.code)
        arg_list = data.get_args(var_list, type_list)
        if arg_list == None:
            erro_print(traceback.extract_stack(), 'Function arguments type not matched')
            return
        pos = func_node.code.find('(')
        func_node.set_code(func_node.code[:pos] + '(' + ', '.join(arg_list) + ')')
        if fa.op == '=' or fa.op == 'body':
            return
        res = data.get_tmp_var()
        data.tmp_dict[res] = {'type': return_type, 'dim': '1*1'}
        son = node

        l1, r1 = find_scope_func(data.func_dict[node.expr[:node.expr.find('(')]]['raw_func'], 0)
        param1 = str(data.func_dict[node.expr[:node.expr.find('(')]]['raw_func'][l1:r1]).split(',')
        j = 0
        while j < len(param1):
            li = param1[j].split(' ')
            if li[0] == "float64":
                var_list[j] = recong_float(var_list[j], False)
            j = j + 1
        func_node.set_code(func_node.code[:pos] + '(' + ', '.join(var_list) + ')')

        while fa.op != 'body':
            son = fa
            fa = fa.father
        for i in range(len(fa.children)):
            if fa.children[i] == son:
                func_line = Node(op='=')
                func_line.set_code('{} = {}'.format(res, func_node.code))
                fa.add_child(func_line, i)
                func_line.generate_code()
                break
        func_node.set_code(res)
    else:
        erro_print(traceback.extract_stack(), f"Function [{func_name}] use error!")


def assignment_node_process(data: Data, node: Node, pos: int):
    # node.expr[pos] is '='

    left_str = node.expr[:pos].strip()
    right_str = node.expr[pos + 1:].strip()
    loop_range = []
    var_dicts = {**data.global_vars, **data.tmp_dict, **data.const_dict}
    # var_dicts = {'a':{'dim':'3*3', 'type':'siint32'}, 'q':{'dim':'1*3', 'type':'siint32'}}
    if right_str[0] == '{' and bracket_match(right_str, 0) == len(right_str) - 1:
        for var in var_dicts.keys():
            if left_str.find(var) == 0:
                dims = var_dicts[var]['dim'].split('*')
                if len(dims) == 2 and (dims[0] == '1' or dims[1] == '1'):
                    if dims[0] == '1':
                        dims = [dims[1]]
                    else:
                        dims = [dims[0]]
                if left_str == var:
                    left_str += '[]' * len(dims)
                post = left_str[len(var):].strip()
                layer = 0
                loop_var = var
                # 循环处理多维向量（矩阵）不同维度
                while post != '' and post[0] == '[':
                    r = bracket_match(post, 0)
                    s = post[1:r]
                    post = post[r + 1:].strip()
                    if s == '':
                        t = data.get_tmp_var()
                        data.tmp_dict[t] = {'type': 'siint32', 'dim': '1*1'}
                        loop_var += f'[{t}]'
                        loop_range.append([t, '0', str(int(dims[layer]) - 1)])
                    elif ':' in s:
                        beg = s.split(':')[0].strip()
                        end = s.split(':')[1].strip()
                        if int(beg) > int(end):
                            erro_print(traceback.extract_stack(),
                                       "Start index({}) is greater than end index({})!".format(beg, end))
                        if (int(end)) >= int(dims[layer]) or int(beg) < 0:
                            erro_print(traceback.extract_stack(), "Illegal index {}, {}!".format(beg, end))
                        t = data.get_tmp_var()
                        data.tmp_dict[t] = {'type': 'siint32', 'dim': '1*1'}
                        loop_var += f'[{t}]'
                        loop_range.append([t, beg, end])
                    else:
                        loop_var += f'[{s}]'
                    layer += 1
                new_stmt = ''
                if right_str.find(',') == -1:
                    init = right_str[1:-1].strip()
                    for i in range(len(loop_range)):
                        new_stmt += f'FOR{i + 1} ({loop_range[i][0]}={loop_range[i][1]}:{loop_range[i][2]})'
                        new_stmt += '\n'
                    if init == 'I':
                        new_stmt += f'IF1({loop_range[0][0]} == {loop_range[1][0]})\n'
                        new_stmt += f'{loop_var} = 1;\n'
                        new_stmt += f'ELSE1\n'
                        new_stmt += f'{loop_var} = 0;\nENDIF1'
                    else:
                        # 全部等于init
                        new_stmt += f'{loop_var} = {init};'
                    new_stmt += '\n'
                    for i in range(len(loop_range)):
                        new_stmt += f'ENDFOR{len(loop_range) - i}'
                        new_stmt += '\n'
                else:
                    if right_str.find(';') == -1:
                        vals = right_str[1:-1].split(',')
                        if int(loop_range[0][2]) - int(loop_range[0][1]) + 1 != len(vals):
                            erro_print(traceback.extract_stack(), 'Assignment wrong! Value numbers not matched.')
                        for i in range(len(vals)):
                            new_stmt += f'{loop_var.replace(loop_range[0][0], str(int(loop_range[0][1]) + i))} = {vals[i].strip()};'
                            new_stmt += '\n'
                    else:
                        # 矩阵的初始化赋值
                        vals = right_str[1:-1].split(';')
                        vals = [line.strip().split(',') for line in vals]
                        if int(loop_range[0][2]) - int(loop_range[0][1]) + 1 != len(vals) and int(
                                loop_range[1][2]) - int(loop_range[1][1]) + 1 != len(vals)[0]:
                            erro_print(traceback.extract_stack(), 'Assignment wrong! Value numbers not matched.')
                        for i in range(len(vals)):
                            for j in range(len(vals[0])):
                                tmp_s = f'{loop_var.replace(loop_range[0][0], str(int(loop_range[0][1]) + i))} = {vals[i][j].strip()};'
                                new_stmt += tmp_s.replace(loop_range[1][0], str(int(loop_range[1][1]) + j))
                                new_stmt += '\n'
                return new_stmt
    else:
        left_var, right_var = '', ''
        loop_range_left, loop_range_right = [], []
        if left_str.find(':') == -1 and right_str.find(':') == -1:
            array_pattern = r'[^[\]\s]+(\[\])+'
            flag = False
            if re.match(array_pattern, left_str):
                left_var = left_str.rstrip('[]').strip()
            if re.match(array_pattern, right_str):
                right_var = right_str.rstrip('[]').strip()
            # 两个向量/矩阵直接赋值的情况，则直接返回
            if left_var != '' and right_var != '' and left_var in var_dicts.keys() and right_var in var_dicts.keys():
                return f'{left_var} = {right_var};'
            else:
                pass
        # case: 等号左边的字符串是a[], a[1:2], a[0][]形式，右边为向量/矩阵名
        if is_special_vector(left_str, var_dicts) and right_str in var_dicts.keys():
            dims = var_dicts[right_str]['dim'].split('*')
            if len(dims) == 2 and (dims[0] == '1' or dims[1] == '1'):
                if dims[0] == '1':
                    dims = [dims[1]]
                else:
                    dims = [dims[0]]
            right_var = right_str
            right_str += '[]' * len(dims)
            left_var = left_str.split('[')[0].strip()
        elif is_special_vector(right_str, var_dicts) and left_str in var_dicts.keys():
            dims = var_dicts[left_str]['dim'].split('*')
            if len(dims) == 2 and (dims[0] == '1' or dims[1] == '1'):
                if dims[0] == '1':
                    dims = [dims[1]]
                else:
                    dims = [dims[0]]
            left_var = left_str
            left_str += '[]' * len(dims)
            right_var = right_str.split('[')[0].strip()
        elif is_special_vector(left_str, var_dicts) and is_special_vector(right_str, var_dicts):
            left_var = left_str.split('[')[0].strip()
            right_var = right_str.split('[')[0].strip()
        else:
            return ''
        post_left = left_str[len(left_var):].strip()
        post_right = right_str[len(right_var):].strip()
        loop_var_left, loop_var_right = left_var, right_var
        layer = 0
        beg, end = 0, 0
        left_dims = var_dicts[left_var]['dim'].split('*')
        right_dims = var_dicts[right_var]['dim'].split('*')
        if len(left_dims) == 2 and (left_dims[0] == '1' or left_dims[1] == '1'):
            if left_dims[0] == '1':
                left_dims = [left_dims[1]]
            else:
                left_dims = [left_dims[0]]
        if len(right_dims) == 2 and (right_dims[0] == '1' or right_dims[1] == '1'):
            if right_dims[0] == '1':
                right_dims = [right_dims[1]]
            else:
                right_dims = [right_dims[0]]
        # 获取左侧循环的变量名、循环的范围
        while post_left.find('[') == 0:
            r = bracket_match(post_left, 0)
            s = post_left[1:r]
            post_left = post_left[r + 1:].strip()
            if s == '':
                t = data.get_tmp_var()
                data.tmp_dict[t] = {'type': 'siint32', 'dim': '1*1'}
                loop_var_left += f'[{t}]'
                loop_range_left.append([t, '0', str(int(left_dims[layer]) - 1)])
            elif ':' in s:
                beg = s.split(':')[0].strip()
                end = s.split(':')[1].strip()
                if int(beg) > int(end):
                    erro_print(traceback.extract_stack(),
                               "Start index({}) is greater than end index({})!".format(beg, end))
                if (int(end)) >= int(left_dims[layer]) or int(beg) < 0:
                    erro_print(traceback.extract_stack(), "Illegal index {}, {}!".format(beg, end))
                t = data.get_tmp_var()
                data.tmp_dict[t] = {'type': 'siint32', 'dim': '1*1'}
                loop_var_left += f'[{t}]'
                loop_range_left.append([t, beg, end])
            else:
                loop_var_left += f'[{s}]'
            layer += 1
        layer_l, layer_r = 0, 0
        # 获取右侧循环的变量名、循环的范围
        while post_right.find('[') == 0:
            r = bracket_match(post_right, 0)
            s = post_right[1:r]
            post_right = post_right[r + 1:].strip()
            if s == '':
                loop_range_right.append(['0', str(int(right_dims[layer_r]) - 1)])
                l_beg, l_end = int(loop_range_left[layer_l][1]), int(loop_range_left[layer_l][2])
                if (l_end - l_beg + 1) != int(right_dims[layer_r]):
                    erro_print(traceback.extract_stack(), "Vector/Matrix dim not match!")
                if l_beg > 0:
                    loop_var_right += f'[{loop_range_left[layer_l][0]}-{str(l_beg)}]'
                else:
                    loop_var_right += f'[{loop_range_left[layer_l][0]}]'
                layer_l += 1
            elif ':' in s:
                beg = s.split(':')[0].strip()
                end = s.split(':')[1].strip()
                if int(beg) > int(end):
                    erro_print(traceback.extract_stack(),
                               "Start index({}) is greater than end index({})!".format(beg, end))
                if (int(end)) >= int(right_dims[layer_r]) or int(beg) < 0:
                    erro_print(traceback.extract_stack(), "Illegal index {}, {}!".format(beg, end))
                r_beg = int(beg)
                r_end = int(end)
                l_beg = int(loop_range_left[layer_l][1])
                l_end = int(loop_range_left[layer_l][2])
                if (l_end - l_beg) != (r_end - r_beg):
                    erro_print(traceback.extract_stack(), "Vector/Matrix dim not match!")
                if l_beg == r_beg:
                    loop_var_right += f'[{loop_range_left[layer_l][0]}]'
                elif l_beg < r_beg:
                    loop_var_right += f'[{loop_range_left[layer_l][0]}+{r_beg - l_beg}]'
                else:
                    loop_var_right += f'[{loop_range_left[layer_l][0]}-{l_beg - r_beg}]'
                layer_l += 1
            else:
                loop_var_right += f'[{s}]'
            layer_r += 1
        new_stmt = ''
        for i in range(len(loop_range_left)):
            new_stmt += f'FOR{i + 1} ({loop_range_left[i][0]}={loop_range_left[i][1]}:{loop_range_left[i][2]})'
            new_stmt += '\n'
        new_stmt += f"{loop_var_left} = {loop_var_right};\n"
        for i in range(len(loop_range_left), 0, -1):
            new_stmt += f"ENDFOR{i}\n"
        return new_stmt
    return ''


if __name__ == '__main__':
    s1 = r'MatA[1][] = {1}'
    s2 = r'MatA[1][] = {1, 2, 3}'
    s3 = r'MatA[1:2][0:1] = {1}'
    s4 = r'MatA[i][0:1] = {1, 2}'
    s5 = r'MatA[1][] = VecC[]'
    s6 = r'MatA[][] = {0}'
    s7 = r'MatA[][1] = {1}'
    s8 = r'MatA[][] = MatD[][]'
    s9 = r'MatA[][] = MatD[0:2][0:2]'
    s10 = r'MatA = {I}'
    node = Node(s10)
    data = Data('./configs/config_test.json')
    pos = node.expr.find('=')
    res = assignment_node_process(data, node, pos)
    print(res)
